//
//  PersonTableViewController.m
//  Paparazzi
//
//  Created by Eric Williams on 10/24/10.
//  Copyright 2010 Eric Williams. All rights reserved.
//

#import "PersonTableViewController.h"
#import "PhotoTableViewController.h"
#import "AddNewContactViewController.h"
#import "UpdateAnimationViewController.h"
#import "FlickrFetcher.h"

#import "Person.h"
#import "Photo.h"

@implementation PersonTableViewController

//@synthesize frController;

#pragma mark -
#pragma mark UI Selectors

#pragma mark -
#pragma mark View lifecycle

- (void)addContact {
	AddNewContactViewController *addNewContactController = [[AddNewContactViewController alloc] init];
	[self.navigationController presentModalViewController: addNewContactController animated: YES];
	[addNewContactController release];
}

- (void) refreshContacts {
	// Load our animation overlay
	UpdateAnimationViewController *updateAnimationViewController = [[UpdateAnimationViewController alloc] init];
	updateAnimationViewController.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
	[self.navigationController presentModalViewController: updateAnimationViewController animated: YES];
	[updateAnimationViewController release];
	
	// Refresh the contacts on a background thread
	[NSThread detachNewThreadSelector: @selector(refreshContactsBackground) toTarget:self withObject:nil];
}

- (void)refreshContactsBackground {
	
	 // *****************************************************
	 // *													*
	 // *		REFRESHING CORE DATA FROM FLICKR SERVERS	*
	 // *		(Called when the user hits update)			*
	 // *													*
	 // *****************************************************

	// Create the autorelease pool for this thread
	NSAutoreleasePool *backgroundPool = [[NSAutoreleasePool alloc] init];
	
	// Collect an array of managed Person's in Core Data
	NSArray *fetchedPeople = [flickrFetcher fetchManagedObjectsForEntity: @"Person" withPredicate: nil];
	
	// Pic Counter
//	int counter = 0;
	
	// For each managed Person in Core Data...
	Person *currPerson;
	for (currPerson in fetchedPeople) {

		// Get the managed Person object's Photo array and mark all as "non-found"
		Photo *currPhoto;
		for (currPhoto in currPerson.photos) {
			currPhoto.foundOnRefresh = @"NO";
		}
				
		// Query Flickr for the photos of this user
//		NSLog([NSString stringWithFormat: @"Searching Flickr for photos by %@...", currPerson.name]);
		NSArray *flickrPhotos = [flickrFetcher photosForUser: currPerson.name];
		NSLog(@"Found photos. Now processing...");
		
		// For each image found on Flickr, check if the image is in Core Data already as a managed Photo
		NSDictionary *currFlickrPhoto;
		for (currFlickrPhoto in flickrPhotos) {
			NSString * currFlickrPhotoName = [[NSString alloc] initWithString: [currFlickrPhoto objectForKey: @"title"]];
			NSString * currFlickrPhotoID = [[NSString alloc] initWithString: [currFlickrPhoto objectForKey: @"id"]];
			
			// TO DO: Predicate should also specify the user in case of multiple 
			NSPredicate *matchPhotoIDPredicate = [NSPredicate predicateWithFormat: @"flickrPhotoID MATCHES %@", currFlickrPhotoID];
			NSArray *fetchedPics = [[NSArray alloc] initWithArray: [flickrFetcher fetchManagedObjectsForEntity: @"Photo" withPredicate: matchPhotoIDPredicate]];

			// If not, add a new managed Photo marked as "found", set its properties, and link that image back to the Person object
			if(fetchedPics.count == 0) {
				
				// Create a new Photo object and insert it into the DB
				Photo *newPhoto = [NSEntityDescription insertNewObjectForEntityForName: @"Photo" inManagedObjectContext: flickrFetcher.managedObjectContext];
				
				// Setup the Photo
				newPhoto.name = currFlickrPhotoName;
				if([currFlickrPhotoName length] == 0) {
					newPhoto.name = @"(untitled)";
				}
				newPhoto.user = currPerson;
				newPhoto.foundOnRefresh = @"YES";
				
				newPhoto.flickrPhotoID = currFlickrPhotoID;
				newPhoto.flickrFarm = [[currFlickrPhoto objectForKey: @"farm"] stringValue];
				newPhoto.flickrSecret = [currFlickrPhoto objectForKey: @"secret"];
				newPhoto.flickrServer = [currFlickrPhoto objectForKey: @"server"];
				
				// Link the person to it
				[currPerson addPhotosObject: newPhoto];
				
//				NSLog([NSString stringWithFormat: @"New pic %d", counter++]);
			}
			
			// If so, remark the Photo as "found"
			else {
				Photo *oldPhoto = [fetchedPics objectAtIndex: 0];
				oldPhoto.foundOnRefresh = @"YES";
//				NSLog([NSString stringWithFormat: @"Old pic %d", counter++]);
			}
			
			// Alloc-->Release combo for tight loop memory control of ballooning autorelease pool
			[currFlickrPhotoName release];
			[currFlickrPhotoID release];
			[fetchedPics release];
		}
		
		// For each Photo in the photo array for this person
		for (currPhoto in currPerson.photos) {
			// If the photo still hasn't been found (i.e. The Flickr user has removed/renamed this previously added photo), delete the Photo object reference to it
			if (currPhoto.foundOnRefresh != @"YES") {
				[flickrFetcher.managedObjectContext deleteObject: currPhoto];
//				NSLog([NSString stringWithFormat: @"Deleteing pic %d", counter++]);
			}
		}
		
		// Set the users icon to one of their photos at random
		Photo *photo = [currPerson.photos anyObject];
		currPerson.icon = [flickrFetcher dataForPhotoID:photo.flickrPhotoID fromFarm:photo.flickrFarm onServer:photo.flickrServer withSecret:photo.flickrSecret inFormat: FlickrFetcherPhotoFormatSquare];
	 }
	
	// Save CoreData changes
	[flickrFetcher.managedObjectContext save: nil];
	[self.tableView reloadData];

	// Return to the main thread
	[self performSelectorOnMainThread: @selector(refreshContactsBackgroundDone) withObject:nil waitUntilDone:NO];
	
	// Release our pool
	[backgroundPool release];
}


- (void) refreshContactsBackgroundDone {
	// Unload the animation overlay
	[self.navigationController dismissModalViewControllerAnimated: YES];
}


- (void)viewDidLoad {
    [super viewDidLoad];
	
	UIBarButtonItem *contactsAdd = [[UIBarButtonItem alloc] initWithBarButtonSystemItem: UIBarButtonSystemItemAdd target:self action: @selector(addContact)];
	self.navigationItem.leftBarButtonItem = contactsAdd;
	[contactsAdd release];
	
	UIBarButtonItem *contactsRefresh = [[UIBarButtonItem alloc] initWithBarButtonSystemItem: UIBarButtonSystemItemRefresh target:self action:@selector(refreshContacts)];
	self.navigationItem.rightBarButtonItem = contactsRefresh;
	[contactsRefresh release];
	
	// Setup our fetcher, clear the cache of the previous people's results, and refill it
	flickrFetcher = [FlickrFetcher sharedInstance];
	frController = [[flickrFetcher fetchedResultsControllerForEntity: @"Person" withPredicate: nil] retain];
	[NSFetchedResultsController deleteCacheWithName: frController.cacheName];
	NSError *error = nil;
	[frController performFetch: &error];
	
	// Create the header image view to be passed in later by the delegate
	UIImage *contactsImage = [UIImage imageNamed: @"Contacts.png"];
	contactsHeaderImageView = [[UIImageView alloc] initWithImage: contactsImage];
	
    // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
    // self.navigationItem.rightBarButtonItem = self.editButtonItem;
}



- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];

	// Clear the cache of the previous people's results and refill it
	[NSFetchedResultsController deleteCacheWithName: frController.cacheName];
	NSError *error = nil;
	[frController performFetch: &error];	
	
	[self.tableView reloadData];
}

/*
- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
}
*/
/*
- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];
}
*/
/*
- (void)viewDidDisappear:(BOOL)animated {
    [super viewDidDisappear:animated];
}
*/

/*
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
    // Return YES for supported orientations
    return (
			(interfaceOrientation == UIInterfaceOrientationPortrait) ||
			(interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown) ||
			(interfaceOrientation == UIInterfaceOrientationLandscapeLeft)
			);
}
*/


#pragma mark -
#pragma mark Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    // Return the number of sections.
	NSInteger sectionCount = [[frController sections] count];
	
	// If sections is not a non-0 value, make it at least one
	if (sectionCount == 0) {
		sectionCount = 1;
	}
	
    return sectionCount;
}


- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    // Return the number of rows in the section (i.e. number of users)
	
	NSArray *sections = [frController sections];
	NSInteger rowCount = 0;
	
	// If there's a section, count its rows
	if([sections count]) {
		id <NSFetchedResultsSectionInfo> sectionInfo = [sections objectAtIndex: section];
		rowCount = [sectionInfo numberOfObjects];
	}

	return rowCount;
}


// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    
    static NSString *CellIdentifier = @"Cell";
    
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
    }
	
    // Configure the cell...
	Person *person = [frController objectAtIndexPath: indexPath];
	cell.textLabel.text = person.name;
	
	NSInteger picCount = [person.photos count];
	if(picCount == 0) {
		cell.detailTextLabel.text = @"No photos";
	}
	else if (picCount == 1) {
		cell.detailTextLabel.text = @"1 photo";
	}
	else {
		cell.detailTextLabel.text = [NSString stringWithFormat: @"%d photos", picCount];
	}

	// Set the contact's icon image
	UIImage *image = [UIImage imageWithData: person.icon];
	cell.imageView.image = image;
	cell.imageView.contentMode = UIViewContentModeScaleAspectFit;
	
	if (indexPath.row % 2 == 0) {
		cell.backgroundColor = [UIColor colorWithRed:0.95 green:0.95 blue:0.95 alpha:1.0];
	}
	
    return cell;
}

-(void) tableView: (UITableView*) tableView willDisplayCell:(UITableViewCell*) cell forRowAtIndexPath:(NSIndexPath*) indexPath {
	if (indexPath.row % 2 == 0) {
		cell.backgroundColor = [UIColor colorWithRed:0.95 green:0.95 blue:0.95 alpha:1.0];
	}	
}

/*
// Override to support conditional editing of the table view.
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
    // Return NO if you do not want the specified item to be editable.
    return YES;
}
*/



// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
    
    if (editingStyle == UITableViewCellEditingStyleDelete) {
		
		// Get a complete set of pointers to all the managed data we'll delete 
		Person *person = [frController objectAtIndexPath: indexPath];
		NSSet *photos = person.photos;
		
		// Delete the Person (and any associated Photos) from Core Data
		[flickrFetcher.managedObjectContext deleteObject: person];
		Photo *currPhoto = nil;
		for(currPhoto in photos) {
			[flickrFetcher.managedObjectContext deleteObject: currPhoto];
		}
		
		// Save our deletions
		[flickrFetcher.managedObjectContext save: nil];
		
		// Clear the fetch cache and reload it
		[NSFetchedResultsController deleteCacheWithName: frController.cacheName];
		NSError *error = nil;
		[frController performFetch: &error];
		
        // Delete the row from the data source
        [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
		
		// call our delegate and tell it that we deleted a contact
//		[contactDelegate contactDeleted];
    }   
    else if (editingStyle == UITableViewCellEditingStyleInsert) {
        // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
    }  
}

/*
// Override to support rearranging the table view.
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath {
}
*/


/*
// Override to support conditional rearranging of the table view.
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath {
    // Return NO if you do not want the item to be re-orderable.
    return YES;
}
*/


#pragma mark -
#pragma mark Table view delegate

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    
	// Create a new Table View
	PhotoTableViewController *photoTableViewController = [[PhotoTableViewController alloc] initWithStyle: UITableViewStylePlain];
	Person *person = [frController objectAtIndexPath: indexPath];
	photoTableViewController.person = person;
	photoTableViewController.title = [[person name] stringByAppendingFormat: @"'s Photos"];
	photoTableViewController.multiUser = NO;
		 
	[self.navigationController pushViewController: photoTableViewController animated: YES];
	[photoTableViewController release];
}

// Used to place an image in the main header
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
	if(section == 0) {
		return contactsHeaderImageView;
	}
	else {
		return nil;
	}
}

// Used to size the main header 
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
	if(section == 0) {
		return 60.0;
	}
	else {
		return 0;
	}
}

// Used to beef up the height on the other cells
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
	return 60;
}


#pragma mark -
#pragma mark Memory management

- (void)didReceiveMemoryWarning {
    // Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];
    
    // Relinquish ownership any cached data, images, etc that aren't in use.
}

- (void)viewDidUnload {
    // Relinquish ownership of anything that can be recreated in viewDidLoad or on demand.
    // For example: self.myOutlet = nil;
}


- (void)dealloc {
	[frController release];
    [super dealloc];
}


@synthesize flickrFetcher;
@synthesize frController;
@synthesize contactsHeaderImageView;
@end

